VSCode での作業を想定してます。
JSDoc コメントの@type
や@typedef
では TypeScript の型ファイルを参照できます。これらのアノテーションを用いて値に型を付けると、例えばmode
の値を入力する時にdevelopment
やproduction
、none
がサジェストされるようになります。
webpack 型をインストール
webpack
とwebpack-cli
はインストール済なら、もう1つ@types/webpack
もインストールします。
yarn add -D @types/webpack
これで型定義部分でimport('webpack')
のように書くと@types/webpack
が提供する型を参照できるようになりました。
型を付ける
単に設定オブジェクト全体に型を付けたい場合はConfiguratiion
を使います。ここで言う設定オブジェクトはoutput
やentry
、module
など全てを持ったオブジェクトの事です。
オブジェクト
これは以下のように設定します。
/**
* @type {import('webpack').Configuration}
*/
module.exports = {
/* 設定の中身 */
};
これだけでmode
などにサジェストされるようになったはずです。
Webpack の設定には配列で複数の設定オブジェクトを置いたり、関数で設定オブジェクトを置いたりといくつか別の形態を持ちます。
配列
配列の場合はconfiguration
の後ろに[]
を置くだけです。
/**
* @type {import('webpack').Configuration[]}
*/
module.exports = {
/* 設定の中身 */
};
関数
関数の場合は@type
ではなく@returns
を使います。これにより戻り値の型を付けれます。
/**
* @returns {import('webpack').Configuration}
*/
module.exports = () => ({
mode: 'development'
});
ちなみにこの関数は、良くenv
やargv
と名付けられる引数2つを受け取れますが、これらに型を付けたり場合は以下のようにします。
/**
* @param {Object} env
* @param {boolean} env.production
* @param {Object} argv
* @param {import('webpack').Configuration['mode']} argv.mode
* @returns {import('webpack').Configuration}
*/
module.exports = (env, argv) => ({
mode: env.production ? 'production' : 'development'
// mode: argv.mode
/* ... */
});
env
は{production: boolean}
なオブジェクトで、argv
は{mode: string}
のようなオブジェクトと型を付けしました。これでプロパティにアクセスする時にproduction
やmode
などがサジェストされます。
プロミス
戻り値には設定オブジェクトを解決するプロミスでも良いので、その場合はこんな感じに。
/**
* @returns {Promise.}
*/
module.exports = () =>
new Promise(resolve => {
resolve(/* ... */);
});
共通設定を切り出す
共通設定を切り出すということは設定オブジェクトConfiguration
から幾つかのプロパティを取り出して、必要なプロパティだけの新たなオブジェクト型を定義する必要があります。
当たらなオブジェクト型を定義するには@typedef
アノテーションを使います。
例えばこのアノテーションは以下のようにすると{value: string}
な型のオブジェクトをFoo
という名前で定義できます。Foo
を使うときには、これまでと同じく@type
で使います。
/**
* @typedef {Object} Foo
* @property {string} Foo.value
*/
/**
* @type {Foo}
*/
const foo = {value: 'something'};
設定オブジェクトが配列な時、mode
というのは実行時に渡した環境変数などで決める内容なので切り分けると効率が良さそうです。それには{mode: ...}
という内容の共通オブジェクトCommonWeConfiguration
を定義して、適当な変数にその型を付けてあげます。
/**
* @typedef {Object} CommonWebpackConfiguration
* @property {import('webpack').Configuration['mode']} CommonWebpackConfiguration.mode
*/
/**
* @type {CommonWebpackConfiguration}
*/
const common = {
mode:
process.env.NODE_ENV === "production"
? "production"
: "development"
};
Configuration
はinterface
ですが、ここから更に各プロパティへアクセスするには['property']
にインデックスにアクセスするような形で書きます。